package boddaert.philippe.cashGame.net;

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;

import org.apache.log4j.Logger;

import boddaert.philippe.cashGame.site.WebPage;

public abstract class WebPageGetter implements IWebPageGetter {

	private final static Logger logger = Logger.getLogger(WebPageGetter.class);

	public final WebPage get(String url) throws IOException {
		if (url == null)
			throw new IllegalArgumentException("url must be setted");

		URL urlWithoutStreamHandler = new URL(url);
		URL connection = new URL(urlWithoutStreamHandler.getProtocol(),
				urlWithoutStreamHandler.getHost(), urlWithoutStreamHandler
						.getPort(), urlWithoutStreamHandler.getFile(),
				getURLStreamHandler());

		logger.debug("connexion to url " + url);

		URLConnection openConnection = connection.openConnection();
		if (openConnection == null)
			throw new IOException("Can't connect to url : " + url);

		openConnection.connect();

		WebPage page = new WebPage(url);

		page.setContent(readStream(openConnection.getContentLength(),
				openConnection.getInputStream()));
		logger.debug("page is retrieved");
		return page;
	}

	protected abstract URLStreamHandler getURLStreamHandler();

	private static Object readStream(int length, java.io.InputStream stream)
			throws java.io.IOException {
		final int buflen = Math.max(1024, Math.max(length, stream.available()));
		byte[] buf = new byte[buflen];
		;
		byte[] bytes = null;

		for (int nRead = stream.read(buf); nRead != -1; nRead = stream
				.read(buf)) {
			if (bytes == null) {
				bytes = buf;
				buf = new byte[buflen];
				continue;
			}
			final byte[] newBytes = new byte[bytes.length + nRead];
			System.arraycopy(bytes, 0, newBytes, 0, bytes.length);
			System.arraycopy(buf, 0, newBytes, bytes.length, nRead);
			bytes = newBytes;
		}

		return new String(bytes);
	}
}
